#!/usr/bin/env python
# -*- coding: utf-8 -*-

# dialogs/image.py

# Copyright 2009-2010 Diego Hansen Hahn (aka DiegoHH) <diegohh90 [at] hotmail [dot] com>

# lazynds is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License.

# lazynds is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with lazynds. If not, see <http://www.gnu.org/licenses/>.

__author__ = "Diego Hansen Hahn"
__version__ = "v2.0.2"

import array
import os
from math import ceil
import struct

import gtk
import gobject

import default

from images import images, palettes

def populate_combo_box(cb, items):
    model = gtk.ListStore(gobject.TYPE_STRING)
    for x in items:
        model.append([x])
    cb.set_model(model)
    cell = gtk.CellRendererText()
    cb.pack_start(cell, True)
    cb.add_attribute(cell, 'text', 0)

def tostring(list):
    colormap = array.array('c')
    for color in list:
        color = map(lambda x: float(x/248.0), color)
        colormap.extend(palettes.tuple2gba(*color))
    return colormap

class Image:
    def __init__(self, builder, parent):
        self.builder = builder

        self.dialog = self.builder.get_object('image_dialog')
        self.dialog.set_transient_for(parent)

        self.viewport = self.builder.get_object('vwp_palette2')
        self.palette_widget = palettes.PaletteWidget()
        self.viewport.add(self.palette_widget)
        self.palette_widget.set_button_event_two(True)
        self.palette_widget.show()

        self.box_mode_list = self.builder.get_object('box_mode_list2')
        populate_combo_box(self.box_mode_list, [' Unidimensional', ' Bidimensional'])
        self.box_mode_list.connect('changed', self.on_mode_changed)

        self.box_codec_list = self.builder.get_object('box_codec_list2')
        populate_combo_box(self.box_codec_list, [' 1BPP Linear Reverso', ' 2BPP Linear Reverso', ' 4BPP Linear Reverso', ' 8BPP Linear'])
        self.box_codec_list.connect('changed', self.on_codec_changed)

        self.padding_widget = self.builder.get_object('padding')

    def run(self, file):
        self.reader = images.Reader(file)
        self.mode = None
        self.bitdepth = None

        self.box_mode_list.set_active(-1)
        self.box_codec_list.set_active(-1)

        self.padding_widget.set_adjustment(gtk.Adjustment(0, 0, os.path.getsize(file.name), 1, 1, 0))

        w = 0
        self.palette_widget.clear_colors()
        for y in range(1,161, 10):
            for x in range(1,161, 10):
                color = palettes.Colors(w, (0,0,0), (x,y))
                self.palette_widget.add_color(color)
                w += 1

        while True:
            if self.dialog.run() == gtk.RESPONSE_OK:
                if not self.mode:
                    default.Error(self.dialog, '''Nenhum modo foi selecionado.''')
                    self.box_mode_list.grab_focus()
                elif not self.bitdepth:
                    default.Error(self.dialog, '''Nenhum codec foi selecionado.''')
                    self.box_codec_list.grab_focus()
                else:
                    # Gera uma nova paleta, já que as cores podem ter sido trocadas de posição
                    colormap = [(0, 0, 0)] * 256
                    for color in self.palette_widget:
                        if color.id < 2**self.bitdepth:
                            colormap[color.id] = (int(ceil(color.rgb_value[0]*255)),
                                                int(ceil(color.rgb_value[1]*255)),
                                                int(ceil(color.rgb_value[2]*255)))

                    data, colormap = self.reader.as_data(self.mode, self.bitdepth, colormap)
                    colormap = tostring(colormap)

                    self.palette_widget.colors = []

                    self.dialog.hide()

                    pad = self.padding_widget.get_value_as_int()
                    return data[:(len(data)-pad)], colormap
            else:
                self.dialog.hide()
                return None, None

    def on_mode_changed(self, widget):
        if widget.get_active() == -1:
            return
        self.mode = [1,2][widget.get_active()]

    def on_codec_changed(self, widget):
        if widget.get_active() == -1:
            return
        self.bitdepth = [1,2,4,8][widget.get_active()]

        self.dialog.set_sensitive(False)
        data, colormap = self.reader.read(1, self.bitdepth)

        colormap.extend(zip(*[iter((0,0,0) * (256 - len(colormap)))] * 3))
        c = []
        w = 0
        for color in self.palette_widget:
            c.append(map(lambda x: int(float(x)/255.0*31), colormap[w]))
            color.set_color(map(lambda x: float(x)/255.0, colormap[w]))
            w += 1

        self.palette_widget.refresh()
        self.dialog.set_sensitive(True)